home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
BMUG Revelations
/
BMUG Revelations.toast
/
Utilities
/
System Utility
/
Cache Control
/
No Cache
/
cache.c
next >
Wrap
C/C++ Source or Header
|
1992-01-20
|
7KB
|
188 lines
/* No Cache © 1991 by Tom Thompson, for Overpriced Software. All world rights reserved. */
/* No Cache enables/disables the 68040's on-chip caches on the fly on the Mac Quadras. */
/* It does this by simply hammering at the cache control register. Since the Mac OS */
/* typically runs in the Supervisor mode, we can get away with using such privileged */
/* instructions. Doesn't work under virtual memory, because then OS runs in User mode. */
/* VM driver runs in Supervisor mode to do page faulting. */
#include <Types.h>
#include <asm.h>
#include <pascal.h>
#include <QuickDraw.h>
#include <Windows.h>
#include <Fonts.h>
#include <Dialogs.h>
#include <Menus.h>
#include <Events.h>
#include <OSEvents.h>
#include <OSUtils.h>
#include <Packages.h>
#include <Timer.h>
#include <THINK.h>
#define BUTTON_OFF 0
#define BUTTON_ON 1
#define CACHE_DIALOG_ID 400
#define DISABLE_CACHE 2
#define ENABLE_CACHE 3
#define NIL 0L
#define ON_MASK 0x80008000L /* Mask to extract 68040's cache control bits */
#define ON 0x80008000L /* Both caches are on (bits set) */
#define MC68040 5
#define TOP 40
#define LEFT 40
#define BOTTOM 160
#define RIGHT 470
/* Globals */
EventRecord myEvent;
/* Our home-brew abs() function, since THINK's linker has kittens if we try to use */
/* the ANSI library's abs() in a code resource. */
long abs(long value)
{
if (value < 0)
return (-value);
else
return value;
} /* end abs() */
/* Procedure to see if Mac has a 68040. We bail out quick to prevent trouble if */
/* it doesn't */
Boolean Check_System(void)
{
OSErr error; /* Status of the SysEnvirons trap */
SysEnvRec machineInfo; /* Record with machine-specific data */
DialogPtr checkDialog;
short itemhit;
unsigned char message[51] = "\P Sorry, No Cache only works with 68040-based Macs.";
int cpuType; /* Local variables to hold hardware info */
Boolean noTrouble;
int version_requested; /* Version of SysEnvirons() to use */
noTrouble = TRUE; /* We're not in trouble (yet) */
version_requested = 2; /* MUST set this value if you want valid results */
error = SysEnvirons(version_requested, &machineInfo); /* Get the environment we're running in */
cpuType = machineInfo.processor; /* Extract info */
if (cpuType != MC68040) /* Got an '040? */
{ /* No. Sorry, can't run without it */
ParamText(message, NIL, NIL, NIL);
checkDialog = GetNewDialog(128, NIL, (WindowPtr) -1);
ModalDialog(0L, &itemhit);
DisposDialog(checkDialog);
noTrouble = FALSE;
} /* end if !MC68040 */
return noTrouble;
} /* end Check_System() */
/************* Main program *************/
void main()
{
DialogPtr theDialog;
short itemHit;
unsigned char cacheContents[20];
unsigned long cacheRegister;
short item, itemType;
Rect itemBox;
Handle itemHandle;
long int centerHoriz, centerVert; /* Screen dimensions */
long int frameHoriz, frameVert; /* depth box dimensions */
long int globalLeft, globalTop; /* Global coords to position our windows */
/* Make sure we've got some master pointers */
MoreMasters();
MoreMasters();
MoreMasters();
/* Set up the Mac */
InitGraf(&qd.thePort);
InitFonts();
FlushEvents(everyEvent, 0);
InitWindows();
InitMenus();
TEInit();
InitDialogs(0L);
InitCursor();
if(Check_System() == TRUE)
{
/* Computations to center a window */
centerHoriz = abs(qd.screenBits.bounds.right - qd.screenBits.bounds.left) / 2;
centerVert = abs(qd.screenBits.bounds.bottom - qd.screenBits.bounds.top) / 2;
frameHoriz = centerHoriz - ((RIGHT - LEFT) / 2); /* Calculate offsets from screen center */
frameVert = centerVert - ((BOTTOM - TOP) / 2);
globalLeft = qd.screenBits.bounds.left + frameHoriz; /* Add back into screen coords to get.. */
globalTop = qd.screenBits.bounds.top + frameVert; /* ...global coords on GrayRgn */
/* Set up a window */
theDialog = GetNewDialog(CACHE_DIALOG_ID, 0L, (WindowPtr) -1L);
MoveWindow(theDialog, globalLeft, globalTop, TRUE); /* Move it to screen's center */
asm 68030{
MOVEC CACR, D0 ;Copy cache control register
MOVE.L D0, cacheRegister ;Save copy in our variable
} /* end asm */
/* Debug stuff */
/* NumToString(cacheRegister, cacheContents);
ParamText(cacheContents, NIL, NIL, NIL); */
/* Set up rest of dialog's controls */
if ((cacheRegister & ON_MASK) == ON) /* 68040 caches enabled? */
{ /* Yep, highlight dialog's ON button */
GetDItem(theDialog, ENABLE_CACHE, &itemType, &itemHandle, &itemBox); /* Get our item */
SetCtlValue((ControlHandle) itemHandle, BUTTON_ON); /* Yes, turn button on */
GetDItem(theDialog, DISABLE_CACHE, &itemType, &itemHandle, &itemBox);
SetCtlValue((ControlHandle) itemHandle, BUTTON_OFF); /* Turn button off */
} /* end if == ON */
else /* Nope. They're off, highlight off button */
{
GetDItem(theDialog, DISABLE_CACHE, &itemType, &itemHandle, &itemBox);
SetCtlValue((ControlHandle) itemHandle, BUTTON_ON);
GetDItem(theDialog, ENABLE_CACHE, &itemType, &itemHandle, &itemBox);
SetCtlValue((ControlHandle) itemHandle, BUTTON_OFF);
} /* end else */
ShowWindow(theDialog); /* Make the window visible */
DrawDialog(theDialog); /* Now show our modified controls */
/* Handle events. Loop on bogus stuff, act on a valid item hit value. */
do
{
ModalDialog(0L, &itemHit);
switch (itemHit)
{
case ENABLE_CACHE: /* itemHit = 1 */
asm 68030{
MOVE.L #ON, D0
MOVEC D0, CACR /* Stuff bits into control reg. to turn caches on */
} /* end asm */
;
break;
case DISABLE_CACHE: /* itemHit = 2 */
asm 68030{ /* Note that we have to generate the raw opcode ourselves */
DC.W 0xF4F8 ;CPUSHA BC -- Flush both caches
MOVEQ #0, D0
MOVEC D0, CACR /* Clear all bits in cache reg. to turn caches off */
} /* end asm */
;
break;
default: /* Not a valid item, do nothing */
break;
} /* end switch */
} /* end do */
while ((itemHit < ENABLE_CACHE) && (itemHit > DISABLE_CACHE));
DisposDialog(theDialog);
} /* end if Check_System() */
} /* end main */